package me.zhengjie.modules.other.rest;

import com.qiaofang.applet.common.exception.BusinessException;
import com.qiaofang.applet.constants.UpDownFlagConstants;
import com.qiaofang.applet.service.member.domain.Employee;
import com.qiaofang.applet.service.member.service.EmployeeService;
import com.qiaofang.applet.service.other.domain.Topic;
import com.qiaofang.applet.service.other.service.CityCompanyService;
import com.qiaofang.applet.service.other.service.TopicService;
import com.qiaofang.applet.service.other.service.dto.TopicDto;
import com.qiaofang.applet.service.other.service.dto.TopicListDataDto;
import com.qiaofang.applet.service.other.service.dto.TopicQueryDto;
import com.qiaofang.applet.service.other.service.dto.TopicRelDto;
import com.qiaofang.applet.service.other.service.mapstruct.TopicMapper;
import com.qiaofang.applet.service.property.domain.FirsthandEstate;
import com.qiaofang.applet.service.property.domain.Property;
import com.qiaofang.applet.service.property.service.FirsthandEstateService;
import com.qiaofang.applet.service.property.service.PropertyService;
import com.qiaofang.applet.service.property.service.dto.*;
import com.qiaofang.applet.service.property.service.mapstruct.FirsthandEstateMapper;
import com.qiaofang.applet.service.property.service.mapstruct.PropertyMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.utils.SecurityUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author daiyuxaing
 */
@RestController
@RequestMapping("/api/topic")
@Api(tags = "内容：主题房管理")
public class TopicController {

    public static final String VIEW_LIST = "viewList";
    @Autowired
    private TopicMapper topicMapper;

    @Autowired
    private TopicService topicService;

    @Autowired
    private CityCompanyService cityCompanyService;

    @Autowired
    private FirsthandEstateService firsthandEstateService;

    @Autowired
    private FirsthandEstateMapper firsthandEstateMapper;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private PropertyService propertyService;

    @Autowired
    private PropertyMapper propertyMapper;

    @Autowired
    private UserService userService;

    @PostMapping
    @ApiOperation(value = "添加主题", notes = "添加主题")
    public ResponseEntity<Object> add(@RequestBody @Valid Topic topic) {
        topic.setCorporationCode(SecurityUtils.getCorporationCode());
        topicService.saveTopic(topic);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @GetMapping
    @ApiOperation(value = "查询主题", notes = "查询主题")
    public ResponseEntity<Object> query(TopicQueryDto criteria, Pageable pageable) {
        criteria.setCorporationCode(SecurityUtils.getCorporationCode());
        criteria.setCityCodes(userService.getCityCodeList(SecurityUtils.getCurrentUsername()));
        Page<Topic> page = topicService.findByParams(criteria, pageable);
        List<TopicDto> content = new ArrayList<>();
        if (!CollectionUtils.isEmpty(page.getContent())) {
            content = topicMapper.toDto(page.getContent());
            Map<String, String> cityMap = cityCompanyService.getCityMap(criteria.getCorporationCode());
            for (TopicDto topicDto : content) {
                topicDto.setCityName(StringUtils.defaultString(cityMap.get(topicDto.getCityCode())));
            }
        }
        return new ResponseEntity<>(PageableExecutionUtils.getPage(content, pageable, () -> page.getTotalElements()), HttpStatus.OK);
    }

    @ApiOperation("删除添加主题")
    @DeleteMapping
    public ResponseEntity<Object> delete(@RequestBody Set<String> ids) {
        List<Topic> topics = new ArrayList<>();
        for (String id : ids) {
            Topic topic = new Topic();
            topic.setId(id);
            topics.add(topic);
        }
        topicService.deleteAll(topics);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("修改添加主题")
    @PutMapping
    public ResponseEntity<Object> update(@RequestBody Topic topic) {
        topicService.saveTopic(topic);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @GetMapping("/listTopicData")
    @ApiOperation(value = "查看房源", notes = "查看房源")
    public ResponseEntity<Object> listTopicData(TopicListDataDto topicListDataDto, Pageable pageable) {
        String id = topicListDataDto.getId();
        String viewOrAddList = topicListDataDto.getViewOrAddList();
        Topic topic = topicService.getDomainById(id);
        if (topic == null) {
            throw new BusinessException("主题不存在");
        }
        String topicType = topic.getTopicType();
        if(VIEW_LIST.equals(viewOrAddList) && CollectionUtils.isEmpty(topic.getUniqueUuids())){
            return ResponseEntity.ok(PageableExecutionUtils.getPage(new ArrayList<>(), pageable, () -> 0));
        }
        List<String> uniqueUuids = topic.getUniqueUuids() != null ? new ArrayList<>(topic.getUniqueUuids()) : new ArrayList<>();
        if ("新房".equals(topicType)) {
            FirsthandEstateQueryDto queryDto = new FirsthandEstateQueryDto();
            queryDto.setCorporationCode(SecurityUtils.getCorporationCode());
            if (VIEW_LIST.equals(viewOrAddList)) {
                queryDto.setEstateUniqueUuids(uniqueUuids);
            } else if(!CollectionUtils.isEmpty(uniqueUuids)) {
                queryDto.setNotEstateUniqueUuids(uniqueUuids);
            }
            queryDto.setCityCode(topicListDataDto.getCityCode());
            queryDto.setAreaCode(topicListDataDto.getAreaCode());
            queryDto.setRecommend(StringUtils.equals("是", topicListDataDto.getRecommendStr()));
            queryDto.setUpDownFlag(topicListDataDto.getUpDownFlag());
            queryDto.setEstateName(topicListDataDto.getEstateName());
            queryDto.setUpDownFlag(UpDownFlagConstants.UP_FLAG.getValue());
            Page<FirsthandEstate> page = firsthandEstateService.findAllByParams(queryDto, pageable);
            List<FirsthandEstateAdminListDto> content = new ArrayList<>();
            if (page.getTotalElements() > 0) {
                content = page.getContent().parallelStream().map(firsthandEstateMapper::domainToAdminListDto).collect(Collectors.toList());
            }
            return ResponseEntity.ok(PageableExecutionUtils.getPage(content, page.getPageable(), () -> page.getTotalElements()));
        }

        Map<String, String> cityMap = cityCompanyService.getCityMap(SecurityUtils.getCorporationCode());
        if ("二手房".equals(topicType)) {
            SalePropertyQueryDto queryDto = new SalePropertyQueryDto();
            queryDto.setCorporationCode(SecurityUtils.getCorporationCode());
            if (VIEW_LIST.equals(viewOrAddList)) {
                queryDto.setPropertyUniqueUuids(uniqueUuids);
            } else if(!CollectionUtils.isEmpty(uniqueUuids)) {
                queryDto.setNotPropertyUniqueUuids(uniqueUuids);
            }
            queryDto.setCityCode(topicListDataDto.getCityCode());
            queryDto.setDistrictUuid(topicListDataDto.getDistrictUuid());
            queryDto.setAreaUuid(topicListDataDto.getAreaUuid());
            queryDto.setRecommend(StringUtils.equals("是", topicListDataDto.getRecommendStr()));
            queryDto.setUpDownFlag(topicListDataDto.getUpDownFlag());
            queryDto.setFuzzyQueryStr(topicListDataDto.getFuzzyQueryStr());
            queryDto.setUpDownFlag(UpDownFlagConstants.UP_FLAG.getValue());
            Page<Property> page = propertyService.findAllSaleByParams(queryDto, pageable);
            Page<SalePropertyListAdminDto> result = propertyMapper.convertDomainToSalePropertyListAdminDto(page);
            if (CollectionUtils.isEmpty(result.getContent())) {
                return ResponseEntity.ok(result);
            }
            // 查询员工电话
            Map<String, String> employeeMap = getEmployeeMobilePhone(SecurityUtils.getCorporationCode(), result);
            for (SalePropertyListAdminDto dto : result.getContent()) {
                dto.setMobilePhone(employeeMap.get(dto.getCompanyUuid() + "_" + dto.getEmployeeUuid1()));
                dto.setCityName(cityMap.get(dto.getCityCode()));
            }
            return ResponseEntity.ok(result);
        } else {
            RentPropertyQueryDto queryDto = new RentPropertyQueryDto();
            queryDto.setCorporationCode(SecurityUtils.getCorporationCode());
            if (VIEW_LIST.equals(viewOrAddList)) {
                queryDto.setPropertyUniqueUuids(uniqueUuids);
            } else if(!CollectionUtils.isEmpty(uniqueUuids))  {
                queryDto.setNotPropertyUniqueUuids(uniqueUuids);
            }
            queryDto.setCityCode(topicListDataDto.getCityCode());
            queryDto.setDistrictUuid(topicListDataDto.getDistrictUuid());
            queryDto.setAreaUuid(topicListDataDto.getAreaUuid());
            queryDto.setRecommend(StringUtils.equals("是", topicListDataDto.getRecommendStr()));
            queryDto.setUpDownFlag(topicListDataDto.getUpDownFlag());
            queryDto.setFuzzyQueryStr(topicListDataDto.getFuzzyQueryStr());
            queryDto.setUpDownFlag(UpDownFlagConstants.UP_FLAG.getValue());
            Page<Property> page = propertyService.findAllRentByParams(queryDto, pageable);
            Page<RentPropertyListAdminDto> result = propertyMapper.convertDomainToRentPropertyListAdminDto(page);
            if (CollectionUtils.isEmpty(result.getContent())) {
                return ResponseEntity.ok(result);
            }
            for (SalePropertyListAdminDto dto : result.getContent()) {
                dto.setCityName(cityMap.get(dto.getCityCode()));
            }
            return ResponseEntity.ok(result);
        }
    }

    @ApiOperation("添加房源")
    @PostMapping("/addFy")
    public ResponseEntity<Object> addFy(@RequestBody TopicRelDto topicRelDto) {
        String id = topicRelDto.getId();
        Topic topic = topicService.getDomainById(id);
        if (topic == null) {
            throw new BusinessException("主题不存在");
        }
        int topicNum = (topic.getUniqueUuids() != null ? topic.getUniqueUuids().size() : 0) + topicRelDto.getUniqueUuids().size();
        if (topicNum > 10) {
            throw new BusinessException("一个主题最多只能关联10套房源");
        }

        Set<String> uniqueUuids = topic.getUniqueUuids() != null ? topic.getUniqueUuids() : new HashSet<>();
        uniqueUuids.addAll(topicRelDto.getUniqueUuids());
        topic.setUniqueUuids(uniqueUuids);
        topicService.save(topic);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("移除房源")
    @PostMapping("/removeFy")
    public ResponseEntity<Object> removeFy(@RequestBody TopicRelDto topicRelDto) {
        String id = topicRelDto.getId();
        Set<String> uuids = topicRelDto.getUniqueUuids();
        Topic topic = topicService.getDomainById(id);
        if (topic == null) {
            throw new BusinessException("主题不存在");
        }
        Set<String> uniqueUuids = topic.getUniqueUuids();
        uniqueUuids.removeAll(uuids);
        topic.setUniqueUuids(uniqueUuids);
        topicService.save(topic);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 获取员工手机号码
     *
     * @param corporationCode
     * @param result
     * @return
     */
    private Map<String, String> getEmployeeMobilePhone(String corporationCode, Page<SalePropertyListAdminDto> result) {
        Map<String, String> employeeMap = new HashMap<>();
        List<String> employeeUuids = result.getContent().parallelStream().map(dto -> dto.getEmployeeUuid1()).collect(Collectors.toList());
        List<Employee> employees = employeeService.findAllByEmployeeUuidIn(corporationCode, employeeUuids);
        if (!CollectionUtils.isEmpty(employees)) {
            for (Employee employee : employees) {
                employeeMap.put(employee.getCompanyUuid() + "_" + employee.getEmployeeUuid(), employee.getMobilePhone());
            }
        }
        return employeeMap;
    }
}
